package com.ggboy.sc.pl.project.es.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.engine.VersionConflictEngineException;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms.Bucket;
import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.stereotype.Service;

import com.ggboy.sc.pl.project.es.model.DocEntity;
import com.ggboy.sc.pl.project.es.service.DocService;
import com.ggboy.sc.pl.project.es.util.GsonUtil;

@Service
public class DocServiceImpl implements DocService{

    @Resource(name="localEsClient")
    private ElasticsearchTemplate elasticsearchTemplate;

	@SuppressWarnings("serial")
	@Override
	public Map<String, Object> addDoc(DocEntity docEntity) {
		IndexQuery index =null;
		List<IndexQuery> list =new ArrayList<IndexQuery>();
		for(int i=0;i<1;i++) {
			index = new IndexQuery();
			docEntity.setCreateTime(new Date());
            index = new IndexQueryBuilder().withObject(docEntity).build();
            list.add(index);
		}
		elasticsearchTemplate.bulkIndex(list);
		Map<String,Object> m=new HashMap<String,Object>(){{
			put("msg","导入["+list.size()+"]个文档成功");
		}};
		
		return m;
	}

	@Override
	public Map<String, Object> update(String index, String type,Map<String, Object> data) {
		Map<String,Object> map=new HashMap<String,Object>();
		GetResponse getRessponse=null;
		try {
			String id=data.get("id").toString();
			getRessponse=get(index, type, id);
			
			UpdateResponse updateResponse=elasticsearchTemplate.getClient()
					.prepareUpdate(index,type,id)
					.setVersion(getRessponse.getVersion())
					.setDoc(data).execute().actionGet();
			map.put("msg", "数据为["+id+"]更新成功,当前数据:"+data+"，当前数据版本为：["+getRessponse.getVersion()+"]");
		}catch (VersionConflictEngineException e) {
			map.put("msg", "版本号不一致可能已经被修改了,当前版本为：\r\n"+getRessponse.getVersion());
		}
		return map;
	}
    
	
	public GetResponse get(String index,String type,String id) {
		GetResponse getResponse=elasticsearchTemplate.getClient().prepareGet(index, type, id).get();
		System.out.println("版本号："+getResponse.getVersion());
		return getResponse;
	}

	@SuppressWarnings("serial")
	@Override
	public Map<String, Object> rangeSearch(String index, String type, Map<String, Object> data) {
		String bginTime=(String)data.get("bginTime");
		String endTime=(String)data.get("endTime");
		String word=(String)data.get("word");
		String fileName[]=(String[])data.get("fileName");

        HighlightBuilder highlightBuilder = new HighlightBuilder().field("*").requireFieldMatch(true);
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
		
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        if(StringUtils.isNotBlank(bginTime)&& StringUtils.isNotBlank(endTime)) {
            query.should(QueryBuilders.rangeQuery("createTime").format("yyyy-MM-dd").from(bginTime).to(endTime));
        }
        
		if(fileName!=null && fileName.length>0) {
			for(String file:fileName) {
				query.should(QueryBuilders.matchPhraseQuery(file, word));
			}
		}
        SearchRequestBuilder searchRequestBuilder = elasticsearchTemplate.getClient().prepareSearch(index)
                .setFrom(0).setSize(1000)
                .setTypes(new String[] {"doc","poetry"}) //多表查询
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                .setQuery(query)
                .addSort("_score",SortOrder.DESC)
                .highlighter(highlightBuilder)
                .addAggregation(AggregationBuilders.terms("per_count").field("zcfgContent"))
                .addAggregation(AggregationBuilders.avg("per_avg").field("id"))
                //设置是否按查询匹配度排序
                .setExplain(true); 
        SearchResponse searchResponse = searchRequestBuilder.get();

        Terms per_count = searchResponse.getAggregations().get("per_count");
        List<Bucket> buckets = (List<Bucket>) per_count.getBuckets();
        for(Bucket bucket:buckets){
//            System.out.println(bucket.getKey()+"----"+bucket.getDocCount());
        }
        InternalAvg avg = searchResponse.getAggregations().get("per_avg");
        System.out.println("ID-AVG:"+avg.getValue());
        SearchHits searchHits = searchResponse.getHits();
        SearchHit[] hits = searchHits.getHits();
        List<Object> resultList= new ArrayList<Object>();
        for (int i = 0; i < hits.length; i++) {
            SearchHit hit = hits[i];
            String json = hit.getSourceAsString();
            Map<String,Object> dataMap = GsonUtil.parseObject(json, Map.class);
            dataMap.put("id", hit.getId());
            dataMap.put("index", hit.getIndex());
            dataMap.put("type", hit.getType());
            dataMap.put("total", searchHits.totalHits);
            dataMap.put("score", hit.getScore());
            
            Map<String, HighlightField> result = hit.getHighlightFields();
            if(fileName!=null && fileName.length>0) {
                for(String file:fileName) {
                    HighlightField titleField = result.get(file);
                    if (titleField !=null) {
                        Text[] titleTexts = titleField.fragments();
                        String title = "";
                        for (Text text : titleTexts) {
                            title += text;
                        }
                        dataMap.put(file, title);
                    }
                }
            }
            resultList.add(dataMap);
        }
        Map<String,Object> map = new HashMap<String,Object>(){
        	{
        		put("msg","分词高亮数据");
        		put("data",resultList);
        	}
        };
		return map;
	}
    
}
